/**
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.solarchallenge.server.domain;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.solarchallenge.shared.LoginCategory;
import com.google.solarchallenge.shared.dtos.UserAccountDto;
import com.google.solarchallenge.shared.exceptions.InvalidClientInputException;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

/**
 * Domain object for UserAccount.
 *
 * @author Arjun Satyapal
 */
@PersistenceCapable(identityType = IdentityType.APPLICATION,
    detachable = "true")
public class UserAccountDao implements AbstractDao {
  @PrimaryKey
  @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
  private Key key;
  @Persistent
  private String firstName;
  @Persistent
  private String lastName;
  @Persistent
  private String email;
  @Persistent
  private LoginCategory loginCategory;
  @Persistent
  boolean loginAllowed;

  // Other Child Entities.
  @Persistent(dependent="true")
  private ApplicantDao applicantDao;


  @Override
  public StringBuilder getStringBuilder() {
    StringBuilder builder = new StringBuilder("ApproverDao[")
        .append("key:").append(KeyFactory.keyToString(key))
        .append(", firstName:").append(firstName)
        .append(", lastName:").append(lastName)
        .append(", email:").append(email)
        .append(", loginCategory:").append(loginCategory)
        .append(", loginAllowed:").append(loginAllowed)
        .append("].");

    return builder;
  }

  @Override
  public String toString() {
    return getStringBuilder().toString();
  }

  private UserAccountDao() {
  }

  @Override
  public String validate() {
    StringBuilder builder = new StringBuilder("");

    // id will be set only by server. So not checking it.
    if (firstName.isEmpty()) {
      builder.append("firstName is empty.\n");
    }
    if (lastName.isEmpty()) {
      builder.append("lastName is empty.\n");
    }
    if (email.isEmpty()) {
      builder.append("email is empty.\n");
    }

    return builder.toString();
  }

  public void setKey(String key) {
    this.key = KeyFactory.stringToKey(key);
  }

  public Key getKey() {
    return key;
  }

  public String getEncodedKey() {
    return KeyFactory.keyToString(key);
  }

  public String getFirstName() {
    return firstName;
  }

  public String getLastName() {
    return lastName;
  }

  public String getEmail() {
    return email;
  }

  public LoginCategory getLoginCategory() {
    return loginCategory;
  }

  public void setLoginCategory(LoginCategory loginCategory) {
    this.loginCategory = loginCategory;
  }

  public ApplicantDao getApplicantDao() {
    return applicantDao;
  }

  public void setApplicantDao(ApplicantDao applicantDao) {
    this.applicantDao = applicantDao;
  }

  public boolean getIsLoginAllowed() {
    return loginAllowed;
  }

  public void setIsLoginAllowed(boolean isLoginAllowed) {
    this.loginAllowed = isLoginAllowed;
  }

  public static UserAccountDao fromDto(UserAccountDto dto, boolean isCreate) {
    if (!dto.validate().isEmpty()) {
      throw new InvalidClientInputException(
          "Invalid UsAddressDao with Error : [" + dto.validate() + "].");
    }
    if (isCreate && dto.getKey() != null) {
      throw new InvalidClientInputException("Invalid Id[" + dto.getKey()
          + "]. Only server is allowed to set the id."
          + " Clients should not set it.");
    }

    UserAccountDao userAccountDao = new UserAccountDao();
    userAccountDao.firstName = dto.getFirstName();
    userAccountDao.lastName = dto.getLastName();
    userAccountDao.email = dto.getEmail();
    // NOTE : this is unsafe as values sent by client cannot be trusted.
    userAccountDao.loginCategory = dto.getLoginCategory();

    if (!isCreate) {
      if (dto.getKey() == null) {
        throw new InvalidClientInputException(
            "Key is not set for EditRequest.");
      }
      userAccountDao.key = KeyFactory.stringToKey(dto.getKey());
      userAccountDao.loginAllowed = dto.isLoginAllowed();
    }
    return userAccountDao;
  }

  public UserAccountDto toDto() {
    return new UserAccountDto.Builder()
        .setKey(KeyFactory.keyToString(key))
        .setFirstName(firstName)
        .setLastName(lastName)
        .setEmail(email)
        .setLoginCategory(loginCategory)
        .setIsLoginAllowed(loginAllowed)
        .build();
  }
}
